package com.qj.platform.pay.mssm.utils;

import com.qj.base.commons.exception.CommonException;
import com.qj.base.commons.utils.JaxbUtil;
import com.qj.base.commons.utils.JsonUtils;
import com.qj.base.commons.utils.PropertiesUtil;
import com.qj.platform.pay.mssm.domain.MSSMResponse;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.security.PrivateKey;
import java.security.PublicKey;

/**
 * Created by zhijie on 2016/12/13.
 */
public class MSSMPayPlatformUtil {
    private final static Logger logger = LoggerFactory
            .getLogger(MSSMPayPlatformUtil.class);

    public final static String CHARSET = "utf-8";
    private static byte[] keyBytes = null;
    private static PrivateKey privateKey;
    private static PublicKey publicKey;
    private static String encrtptKey;

    public static byte[] getKeyBytes() {
        if (keyBytes == null) {
            try {
                keyBytes = "1122334455667788".getBytes(CHARSET);
            } catch (UnsupportedEncodingException e) {
                keyBytes = "1122334455667788".getBytes();
            }
        }
        return keyBytes;
    }


    public static String aesEncrypt(String data) throws Exception {
        return new String(Base64.encodeBase64((CryptoUtil
                .AESEncrypt(data.getBytes(CHARSET), MSSMPayPlatformUtil.getKeyBytes(), "AES",
                        "AES/ECB/PKCS5Padding", null))), CHARSET);
    }

    public static String getEncrtptKey() throws Exception {
        if (encrtptKey == null) {
            encrtptKey = new String(Base64.encodeBase64(CryptoUtil
                    .RSAEncrypt(getKeyBytes(), getPublicKey(), 2048, 11,
                            "RSA/ECB/PKCS1Padding")), CHARSET);
        }
        return encrtptKey;
    }

    public static <T> T decryptToObj(MSSMResponse response, Class<T> clazz) throws CommonException {
        return new JaxbUtil(clazz).fromXml(decryptToXml(response));
    }

    public static String decryptToXml(MSSMResponse response) throws CommonException {
        try {
            byte[] decodeBase64KeyBytes = Base64.decodeBase64(response.getEncryptKey()
                    .getBytes(CHARSET));
            // ����encryptKey�õ�merchantAESKey
            byte[] merchantAESKeyBytes = CryptoUtil.RSADecrypt(
                    decodeBase64KeyBytes, getPriKey(), 2048, 11,
                    "RSA/ECB/PKCS1Padding");
            // ʹ��base64�����̻�������
            byte[] decodeBase64DataBytes = Base64.decodeBase64(response.getEncryptData()
                    .getBytes(CHARSET));
            // �ý��ܵõ���merchantAESKey����encryptData
            byte[] merchantXmlDataBytes = CryptoUtil.AESDecrypt(decodeBase64DataBytes,
                    merchantAESKeyBytes, "AES", "AES/ECB/PKCS5Padding", null);
            String xml = new String(merchantXmlDataBytes, CHARSET);
            logger.info("返回报文：" + xml);
            return xml;
        } catch (Exception e) {
            logger.error("返回报文解析失败:"+ JsonUtils.toJson(response),e);
            throw new CommonException("返回报文解析失败");
        }
    }

    public static String sha1(String data) throws Exception {
        return new String(Base64.encodeBase64(CryptoUtil
                .digitalSign(data.getBytes(CHARSET), getPriKey(), "SHA1WithRSA")),
                CHARSET);
    }

    public static String getCooperator() {
        return "hzf001";
    }

    private static PrivateKey getPriKey() throws Exception {
        if (privateKey == null) {
            privateKey = CryptoUtil
                    .getRSAPrivateKeyByFileSuffix(
                            PropertiesUtil.getProperty("hpp_prikey_pem"),
//                            "D:\\document\\jie\\git\\pay-plaltform\\doc\\smshmn\\WebContent\\WEB-INF\\classes\\hzf_pkcs8_rsa_private_key_2048.pem",
                            "pem", null, "RSA");
        }
        return privateKey;
    }

    private static PublicKey getPublicKey() throws Exception {
        if (publicKey == null) {
            publicKey = CryptoUtil.getRSAPublicKeyByFileSuffix(PropertiesUtil.getProperty("ms_rsa_pubkey_pem"),"pem","RSA");
//                    "D:\\document\\jie\\git\\pay-plaltform\\doc\\smshmn\\WebContent\\WEB-INF\\classes\\ms_rsa_public_key_2048.pem", "pem", "RSA");
        }
        return publicKey;
    }
}
